/*
    created: 2023/4/23
    filename: UFS.c
    author: 李东霖
    purpose：并查集的实现
*/

#include<stdio.h>
#include<string.h>
#define MAXSIZE 100
//保存元素父结点的数组  
int father[MAXSIZE];

//n个元素初始化
void Init(int n)
{
    // memset(MAXSIZE,0,sizeof(father));
    for(int i = 1;i <= n;++i)
    {
        father[i] = i;//赋值为自己
    }
}

//查找 未进行路径压缩  
//如果是这种查找方式进行的合并，那么他的father[]的指向是一个线性的结构  
int Find0(int elem)
{
    if(father[elem] == elem) return elem;
    return Find0(father[elem]);
}

//查找 进行路径压缩  
//如果进行路径压缩，那么所有的值直接指向他的祖先而不是指向它的上一个元素
//这样他的指向是一个树型结构  
int Find(int elem)
{
    if(father[elem] == elem) return elem;
    father[elem] = Find(father[elem]); //路径压缩 
    return father[elem];
}

//合并  
void Union(int elem1,int elem2)
{
    int fa1 = Find(elem1);
    int fa2 = Find(elem2);
    father[fa1] = fa2;  //将elem1的祖先指向elem2的祖先  
}

//经典应用 你亲戚的亲戚是你的亲戚  

int main()
{
    int n,m,x,y,q;
    printf("人数：");
    scanf("%d",&n);
    Init(n);
    printf("行数：");
    scanf("%d",&m);
    for(int i = 0; i != m;++i)
    {
        scanf("%d%d",&x,&y);
        //合并这两个亲戚
        Union(x,y); 
    }
    printf("输出行数：");
    scanf("%d",&q);
    for(int i = 0;i != q;++i)
    {
        scanf("%d%d",&x,&y);
        if(Find(x) == Find(y)) printf("YES\n");
        else printf("NO\n");
    }

    return 0;
}
